{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "d578142b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "ebfabfc4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow import keras\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "9ea848bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "fashion_mnist = keras.datasets.fashion_mnist\n",
    "(train_image, train_label), (test_image, test_label) = fashion_mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "025705aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_image = train_image / 255.0\n",
    "test_image = test_image / 255.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ba0a741",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_image.shapge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8e9f9723",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 建立输入\n",
    "input = keras.Input(shape=(28, 28))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9ec37ef3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# flatten层看做一个函数\n",
    "x = keras.layers.Flatten()(input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "edb3e01d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 建立dense层\n",
    "x = keras.layers.Dense(32, activation='relu')(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4d2e6719",
   "metadata": {},
   "outputs": [],
   "source": [
    "# dropout层\n",
    "x = keras.layers.Dropout(0.5)(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ff10a6b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = keras.layers.Dense(64, activation='relu')(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e831d8e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 输出层\n",
    "output = x = keras.layers.Dense(10, activation='softmax')(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "50224b82",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 根据输入和输出层建立模型\n",
    "model = keras.Model(inputs=input, outputs=output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b884c558",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 28, 28)]          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 784)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 32)                25120     \n",
      "_________________________________________________________________\n",
      "dropout (Dropout)            (None, 32)                0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 64)                2112      \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                650       \n",
      "=================================================================\n",
      "Total params: 27,882\n",
      "Trainable params: 27,882\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()\n",
    "# None个数维度不必关心"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0c58501d",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer='adam', \n",
    "              loss='sparse_categorical_crossentropy', \n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "0173ab34",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.8755 - accuracy: 0.6681 - val_loss: 0.5424 - val_accuracy: 0.8138\n",
      "Epoch 2/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.6620 - accuracy: 0.7465 - val_loss: 0.5373 - val_accuracy: 0.8141\n",
      "Epoch 3/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.6213 - accuracy: 0.7654 - val_loss: 0.5215 - val_accuracy: 0.8123\n",
      "Epoch 4/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.5971 - accuracy: 0.7738 - val_loss: 0.5081 - val_accuracy: 0.8210\n",
      "Epoch 5/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.5739 - accuracy: 0.7844 - val_loss: 0.5940 - val_accuracy: 0.7627\n",
      "Epoch 6/30\n",
      "1875/1875 [==============================] - 2s 1ms/step - loss: 0.5620 - accuracy: 0.7897 - val_loss: 0.5472 - val_accuracy: 0.8002\n",
      "Epoch 7/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5579 - accuracy: 0.7914 - val_loss: 0.5517 - val_accuracy: 0.7886\n",
      "Epoch 8/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5433 - accuracy: 0.7966 - val_loss: 0.5104 - val_accuracy: 0.8140\n",
      "Epoch 9/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5370 - accuracy: 0.7998 - val_loss: 0.5249 - val_accuracy: 0.8065\n",
      "Epoch 10/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5325 - accuracy: 0.7988 - val_loss: 0.5640 - val_accuracy: 0.7851\n",
      "Epoch 11/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5244 - accuracy: 0.8045 - val_loss: 0.5518 - val_accuracy: 0.7971\n",
      "Epoch 12/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5215 - accuracy: 0.8071 - val_loss: 0.5270 - val_accuracy: 0.8052\n",
      "Epoch 13/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5190 - accuracy: 0.8057 - val_loss: 0.5326 - val_accuracy: 0.8105\n",
      "Epoch 14/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5164 - accuracy: 0.8068 - val_loss: 0.5677 - val_accuracy: 0.7888\n",
      "Epoch 15/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5111 - accuracy: 0.8088 - val_loss: 0.5843 - val_accuracy: 0.7792\n",
      "Epoch 16/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5081 - accuracy: 0.8098 - val_loss: 0.5935 - val_accuracy: 0.7746\n",
      "Epoch 17/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5061 - accuracy: 0.8109 - val_loss: 0.4937 - val_accuracy: 0.8228\n",
      "Epoch 18/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.5009 - accuracy: 0.8141 - val_loss: 0.5669 - val_accuracy: 0.7833\n",
      "Epoch 19/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4941 - accuracy: 0.8154 - val_loss: 0.6413 - val_accuracy: 0.7446\n",
      "Epoch 20/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4959 - accuracy: 0.8167 - val_loss: 0.5422 - val_accuracy: 0.7927\n",
      "Epoch 21/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4910 - accuracy: 0.8179 - val_loss: 0.5345 - val_accuracy: 0.8004\n",
      "Epoch 22/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4885 - accuracy: 0.8181 - val_loss: 0.5508 - val_accuracy: 0.7964\n",
      "Epoch 23/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4842 - accuracy: 0.8195 - val_loss: 0.5532 - val_accuracy: 0.7897\n",
      "Epoch 24/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4801 - accuracy: 0.8225 - val_loss: 0.5844 - val_accuracy: 0.7756\n",
      "Epoch 25/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4824 - accuracy: 0.8207 - val_loss: 0.5319 - val_accuracy: 0.8082\n",
      "Epoch 26/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4800 - accuracy: 0.8223 - val_loss: 0.5559 - val_accuracy: 0.7923\n",
      "Epoch 27/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4799 - accuracy: 0.8217 - val_loss: 0.5302 - val_accuracy: 0.8041\n",
      "Epoch 28/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4772 - accuracy: 0.8220 - val_loss: 0.6344 - val_accuracy: 0.7442\n",
      "Epoch 29/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4741 - accuracy: 0.8228 - val_loss: 0.5810 - val_accuracy: 0.7844\n",
      "Epoch 30/30\n",
      "1875/1875 [==============================] - 3s 1ms/step - loss: 0.4743 - accuracy: 0.8229 - val_loss: 0.5956 - val_accuracy: 0.7744\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x1aefa4cec88>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(train_image, \n",
    "          train_label, \n",
    "          epochs=30,\n",
    "         validation_data=(test_image, test_label))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a84e6f1c",
   "metadata": {},
   "source": [
    "#### 函数式api可以建立多输入模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "85c7590a",
   "metadata": {},
   "outputs": [],
   "source": [
    "input1 = keras.Input(shape=(28, 28))\n",
    "input2 = keras.Input(shape=(28, 28))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "d48f9b3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "x1 = keras.layers.Flatten()(input1)\n",
    "x2 = keras.layers.Flatten()(input2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "7594cf73",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 合并\n",
    "x = keras.layers.concatenate([x1, x2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "aea15aca",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = keras.layers.Dense(32, activation='relu')(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "1cbb2ea8",
   "metadata": {},
   "outputs": [],
   "source": [
    "output = keras.layers.Dense(1, activation='sigmoid')(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "0d5a0e3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = keras.Model(inputs=[input1, input2], outputs=output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "e13c84fe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_4\"\n",
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_8 (InputLayer)            [(None, 28, 28)]     0                                            \n",
      "__________________________________________________________________________________________________\n",
      "input_9 (InputLayer)            [(None, 28, 28)]     0                                            \n",
      "__________________________________________________________________________________________________\n",
      "flatten_7 (Flatten)             (None, 784)          0           input_8[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "flatten_8 (Flatten)             (None, 784)          0           input_9[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_2 (Concatenate)     (None, 1568)         0           flatten_7[0][0]                  \n",
      "                                                                 flatten_8[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "dense_7 (Dense)                 (None, 32)           50208       concatenate_2[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_8 (Dense)                 (None, 1)            33          dense_7[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "dense_9 (Dense)                 (None, 1)            2           dense_8[0][0]                    \n",
      "==================================================================================================\n",
      "Total params: 50,243\n",
      "Trainable params: 50,243\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()\n",
    "# 模型分叉然后合并"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7df9067b",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
